<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
		<title></title>
		<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
		<script type="text/javascript">
			(function(window, document) {
				var w = window,
						doc = document;

				var Kodo = function(selector, context) {
					return new Kodo.prototype.init(selector, context);
				};
				Kodo.prototype = {
					constructor: Kodo,
					length: 0,
					splice: [].splice,
					selector: '',
					init: function(selector, context) { //dom选择的一些判断
						context = context || doc;
						var elm;
						if (!selector) {
							return this;
						}

						if (typeof selector == 'object') {
                            var selector = [selector];
							for (var i = 0; i < selector.length; i++) {
								this[i] = selector[i];
							}
							this.length = selector.length;
							return this;
						} else if (typeof selector == 'function') {
							Kodo.ready(selector);
							return;
						}


						if (selector.charAt(0) == '#' && !selector.match('\\s')) {
							this.selector = selector;

							selector = selector.substring(1);
							elm = doc.getElementById(selector);

							this[0] = elm;
							this.context = context;
							this.length = 1;
							return this;
						} else {
							elm = context.querySelectorAll(selector);
							for (var i = 0; i < elm.length; i++) {
								this[i] = elm[i];
							}

							this.selector = selector;
							this.context = context;
							this.length = elm.length;
							return this;
						}
					},
					css: function (attr, val) { //链式测试
						for (var i = 0; i < this.length; i++) {
							if (typeof attr == 'string') {
								console.log(attr);
								if (arguments.length == 1) {
									return getComputedStyle(this[i], null)[attr];
								}
								this[i].style[attr] = val;
							} else {
								var _this = this[i];
								f.each(attr, function (attr, val) {
									_this.style.cssText += '' + attr + ':' + val + ';';
								});
							}
						}
						return this;
					},
                    width : function(w) {
                        if(arguments.length == 1) {
                            for (var i = 0; i < this.length; i++) {
                                this[i].style.width = w + 'px';
                            }
                        } else {
                            if(this[0].document === doc ) {
                                return this[0].innerWidth;
                            } else if (this[0].nodeType === 9 ){
                                return document.documentElement.clientWidth;
                            } else {
                                return parseInt(getComputedStyle(this[0],null)['width']);
                            }
                        }
                    },
                    height : function(h) {
                        if(arguments.length == 1) {
                            for (var i = 0; i < this.length; i++) {
                                this[i].style.height = h + 'px';
                            }
                        } else {
                            if(this[0].document === doc ) {
                                return this[0].innerHeight;
                            } else if (this[0].nodeType === 9 ){
                                return document.documentElement.clientHeight;
                            } else {
                                return parseInt(getComputedStyle(this[0],null)['height']);
                            }
                        }
                    },
					html: function(value) {
						if (value === undefined) {
							return this[0].innerHTML;
						} else {
							for (var i = 0; i < this.length; i++) {
								this[i].innerHTML = value;
							}
						}
						return this;
					},
					append: function(str) {
						for (var i = 0; i < this.length; i++) {
							domAppend(this[i], 'beforeend', str);
						}
						return this;
					},
					before: function(str) {
						for (var i = 0; i < this.length; i++) {
							domAppend(this[i], 'beforeBegin', str);
						}
						return this;
					},
					after: function(str) {
						for (var i = 0; i < this.length; i++) {
							domAppend(this[i], 'afterEnd', str);
						}
						return this;
					},
					remove: function() { //只能删除自身
						for (var i = 0; i < this.length; i++) {
							this[i].parentNode.removeChild(this[i]);
						}
						return this;
					},

					attr: function(attr, val) {
						for (var i = 0; i < this.length; i++) {
							if (typeof attr == 'string') {
								if (arguments.length == 1) {
									return this[i].getAttribute(attr);
								}
								this[i].setAttribute(attr, val);
							} else {
								var _this = this[i];
								f.each(attr, function(attr, val) {
									_this.setAttribute(attr, val);
								});
							}
						}
						return this;
					},
					data: function(attr, val) {
						for (var i = 0; i < this.length; i++) {
							if (typeof attr == 'string') {
								if (arguments.length == 1) {
									return this[i].getAttribute('data-' + attr);
								}
								this[i].setAttribute('data-' + attr, val);
							} else {
								var _this = this[i];
								f.each(attr, function(attr, val) {
									_this.setAttribute('data-' + attr, val);
								});
							}
						}
						return this;
					},
					hasClass : function(cls) {
						var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
						var arr = [];
						for (var i = 0; i < this.length; i++) {
							if (this[i].className.match(reg)) arr.push(true);
							else arr.push(false);
						}
						if (arr.indexOf(true) != -1)  return true;
						else  return false;
					},
					addClass: function(cls) {
						var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
						for (var i = 0; i < this.length; i++) {
							if (!this[i].className.match(reg))
								this[i].className += ' ' + cls;
						}
						return this;
					},
					removeClass: function(cls) {
						var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
						for (var i = 0; i < this.length; i++) {
							if (this[i].className.match(reg))
								this[i].className = this[i].className.replace(' ' + cls, '');
						}
						return this;
					},
					find: function(selector) {
						if (!selector) return;
						var context = this.selector;
						return new Kodo(context + ' ' + selector);
					},
					first: function() {
						return new Kodo(this[0])
					},
					last: function() {
						var num = this.length - 1;
						return new Kodo(this[num]);
					},
					eq: function(num) {
						var num = num < 0 ? (this.length - 1) : num;
						return new Kodo(this[num]);
					},
					get: function(num) {
						var num = num < 0 ? (this.length - 1) : num;
						return this[num];
					},
					next: function() {
						return sibling(this[0], "nextSibling");
					},
					prev: function() {
						return sibling(this[0], "previousSibling");
					},
					parent: function() {
						var parent = this[0].parentNode;
						parent && parent.nodeType !== 11 ? parent : null;
						var a = Kodo();
						a[0] = parent;
						a.selector = parent.tagName.toLocaleLowerCase();
						a.length = 1;
						return a;
					},
					parents: function() {
						var a = Kodo(),
								i = 0;
						while ((this[0] = this[0]['parentNode']) && this[0].nodeType !== 9) {
							if (this[0].nodeType === 1) {
								a[i] = this[0];
								i++;
							}
						}
						a.length = i;
						return a;
					},
					//////////////////////
					///////新增事件部分////
					//////////////////////
					on: function(type, selector, fn) {
						if (typeof selector == 'function') {
							fn = selector; //两个参数的情况
							for (var i = 0; i < this.length; i++) {
								if (!this[i].guid) {
									this[i].guid = ++Kodo.guid;
									//guid 不存在，给当前dom一个guid

									Kodo.Events[Kodo.guid] = {};
									//给Events[guid] 开辟一个新对象

									Kodo.Events[Kodo.guid][type] = [fn];
									//给这个新对象，赋予事件数组 "click" : [fn1,...]

									bind(this[i], type, this[i].guid);//绑定事件

								} else {//guid存在的情况
									var id = this[i].guid;
									if (Kodo.Events[id][type]) {
										//如果这存在是当前事件已经存过，不用在绑定事件
										Kodo.Events[id][type].push(fn);
									} else {
										//这是存新事件，所以需要重新绑定一次
										Kodo.Events[id][type] = [fn];
										bind(this[i], type, id);
									}
								}
							}
						} else {
							for (var i = 0; i < this.length; i++) {
								if ( !this[i].deleId ) {
									this[i].deleId = ++Kodo.deleId;

									Kodo.deleEvents[Kodo.deleId] = {};

                                    Kodo.deleEvents[Kodo.deleId][selector] = {};
                                    Kodo.deleEvents[Kodo.deleId][selector][type] = [fn];

                                    delegate(this[i],type,selector);
								} else {
									var id = this[i].deleId,
                                        position = Kodo.deleEvents[id];

                                    if(!position[selector]) {

                                        position[selector] = {};
                                        position[selector][type] = [fn];

                                        delegate(this[i],type,selector);
                                    } else {

                                        if ( position[selector][type] ) {
                                            position[selector][type].push(fn);
                                        } else {
                                            position[selector][type] = [fn];
                                            delegate(this[i],type,selector);
                                        }

                                    }
								}
							}
						}
					},
					off: function(type, selector) {
						if (arguments.length == 0) {
							//如果没传参数，清空所有事件
							for (var i = 0; i < this.length; i++) {
								var id = this[i].guid;
								for (var j in Kodo.Events[id]) {
									delete Kodo.Events[id][j];
								}
							}
						} else if (arguments.length == 1) {
							//指定一个参数，则清空对应的事件
							for (var i = 0; i < this.length; i++) {
								var id = this[i].guid;
								delete Kodo.Events[id][type];
							}
						} else {
							for (var i = 0; i < this.length; i++) {
								var id = this[i].deleId;
								delete Kodo.deleEvents[id][selector][type];
							}
						}
					}
				};
				Kodo.prototype.init.prototype = Kodo.prototype;

				Kodo.Events = []; //事件绑定存放的事件
				Kodo.guid = 0; //事件绑定的唯一标识

				Kodo.deleEvents = []; //事件委托存放的事件
				Kodo.deleId = 0; //事件委托的唯一标识
				function delegate(agent, type, selector) {
					var id = agent.deleId;
					agent.addEventListener(type, function(e) {
						var target = e.target;
						var ctarget = e.currentTarget;
						var bubble = true;

						while (bubble && target != ctarget) {
							if (filiter(agent, selector, target)) {
								for (var i = 0; i < Kodo.deleEvents[id][selector][type].length; i++) {
									bubble = Kodo.deleEvents[id][selector][type][i].call(target, e);
									return bubble;
								}
							}
							target = target.parentNode;
						}
					}, false);

					function filiter(agent, selector, target) {
						var nodes = agent.querySelectorAll(selector);
						for (var i = 0; i < nodes.length; i++) {
							if (nodes[i] == target) {
								return true;
							}
						}
					}
				}

				function bind(dom, type, guid) {
					dom.addEventListener(type, function(e) {
						for (var i = 0; i < Kodo.Events[guid][type].length; i++) {
							Kodo.Events[guid][type][i].call(dom, e); //正确的dom回调
						}
					}, false);
				}

				//////////////////////
				///////新增事件部分////
				//////////////////////

				//工具方法
				Kodo.ready = function(fn) {
					doc.addEventListener('DOMContentLoaded', function() {
						fn && fn();
					}, false);
					doc.removeEventListener('DOMContentLoaded', fn, true);
				};
				Kodo.each = function(obj, callback) {
					var len = obj.length,
							constru = obj.constructor,
							i = 0;

					if (constru === window.f) {
						for (; i < len; i++) {
							var val = callback.call(obj[i], i, obj[i]);
							if (val === false) break;
						}
					} else if (isArray(obj)) {
						for (; i < len; i++) {
							var val = callback.call(obj[i], i, obj[i]);
							if (val === false) break;
						}
					} else {
						for (i in obj) {
							var val = callback.call(obj[i], i, obj[i]);
							if (val === false) break;
						}
					}
				};
				Kodo.get = function(url, sucBack, complete) {
					var options = {
						url: url,
						success: sucBack,
						complete: complete
					};
					ajax(options);
				};
				Kodo.post = function(url, data, sucback, complete) {
					var options = {
						url: url,
						type: "POST",
						data: data,
						success: sucback,
						complete: complete
					};
					ajax(options);
				};
                Kodo.prototype.extend = Kodo.extend = function() {
                    var options = arguments[0];
                    for( var i in options) {
                        this[i] = options[i];
                    }
                };
				function ajax(options) {
					var defaultOptions = {
						url: false, //ajax 请求地址
						type: "GET",
						data: false,
						success: false, //数据成功返回后的回调方法
						complete: false //ajax完成后的回调方法
					};
					for (i in defaultOptions) {
						if (options[i] === undefined) {
							options[i] = defaultOptions[i];
						}
					}

					var xhr = new XMLHttpRequest();
					var url = options.url;
					var params = formatParams(options.data);
					xhr.open(options.type, url);
					xhr.onreadystatechange = onStateChange;
					if (options.type === 'POST') {
						xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
					}
					xhr.send(params ? params : null);

					function onStateChange() {
						if (xhr.readyState == 4) {
							var result,
									status = xhr.status;

							if ((status >= 200 && status < 300) || status == 304) {
								result = xhr.responseText;
								ajaxSuccess(result, xhr)
							} else {
								console.log("ERR", xhr.status);
							}
						}
					}

					function ajaxSuccess(data, xhr) {
						var status = 'success';
						options.success && options.success(data, options, status, xhr)
						ajaxComplete(status)
					}

					function ajaxComplete(status) {
						options.complete && options.complete(status);
					}

					function formatParams(data) {
						var arr = [];
						for (var name in data) {
							arr.push(encodeURIComponent(name) + "=" + encodeURIComponent(data[name]));
						}
						arr.push(("v=" + Math.random()).replace("."));
						return arr.join("&");
					}
				}

				function sibling(cur, dir) {
					while ((cur = cur[dir]) && cur.nodeType !== 1) {}
					return cur;
				}

				function domAppend(elm, type, str) { //实现append、after、before操作
					elm.insertAdjacentHTML(type, str);
				}

				function isArray(obj) {
					return Array.isArray(obj);
				}

				w.f = Kodo;
			})(window, document);
		</script>
	</head>
	<body id="body">
		<button id="btn">新增一个li</button>
		<script type="text/javascript">
			$("#btn").click(function() {
				$("#box ul").append('<li class="testLi">15</li>');
			})
		</script>
		<div id="box" style="color: red;">
			<ul>
				<li class="testLi">11</li>
				<li class="testLi">12</li>
				<li class="testLi">13</li>
				<li class="testLi">14</li>
			</ul>
		</div>
		
		<div id="pox" >
			<ul>
				<li>pox</li>
				<li style="width: 200px;">pox</li>
				<li>pox</li><li>pox</li>
				<li>pox</li>
                <span>我是span</span>
			</ul>
		
		</div>
		
		<div class="test">
			<b>123</b>
		</div>
		<div class="test">
			<span class="test-span"></span>
			<b>321</b>
		</div>
		<b class="one-b"></b>

		<script type="text/javascript">

            var pox = document.getElementById('pox');
            console.log(f(document).width());
            console.log(f(window).width());
            console.log(f("#pox li").width(100));
		</script>
	</body>
</html>
